<?php
namespace App\Libs\Passport;
use \App\Libs\Base\Constant;
use \App\Libs\Exception\RuntimeException;
use \App\Libs\Helper\PasswordHelper;
class ForgotPassword extends \App\Libs\Base\Singleton
{
    protected $userTable = 't_hera_user';
    private static function getCode($token) {
        return \App\Libs\Helper\CryptHelper::encrypt($token . ':' . time());
    }

    private static function generate($token) {
        $code = urlencode(self::getCode($token));

        return BASE_URL . '/passport/forgot_reset.html?code=' . $code;
    }

    public function forgot($token, $captcha = NULL) {
        $type = NULL;
        if (preg_match(Constant::MOBILE_REGREX, $token)) {
            $type = 'mobile';
        } else if(preg_match(Constant::EMAIL_REGREX, $token)) {
            $type = 'email';
        } else {
            //$type = 'nickname';
            throw RuntimeException::instance(Constant::NOT_SUPPORT);
        }
        $info = \App\Libs\User\User::getUserInfo(array($type => $token));
        if ($info === NULL) {
            throw RuntimeException::instance(Constant::ACCOUNT_NOT_EXISTS);
        }
        /*
        if ($type === 'nickname') {
            if ( ! empty($info['mobile'])) {
                $type = 'mobile';
                $token = $info['mobile'];
            } else {
                $type = 'email';
                $token = $info['email'];
            }
        }
        */
        // send
        $url = self::generate($info['id']);
        if ($type === 'mobile') {
            \App\Libs\Validate\CaptchaValidator::check($token, $captcha);
        } else if ($type === 'email') {
            $this->byEmail($info, $url);
        }

        return array(
            'type' => $type,
            'token' => $token,
            'url' => $type === 'mobile' ? $url : NULL,
        );
    }

    public function reset($code, $password) {
        $info = \App\Libs\Helper\CryptHelper::decrypt($code);
        if (empty($info)) {
            throw RuntimeException::instance(Constant::ACTIVE_CODE_EXPIRE);
        }
        list($id, $time) = explode(':', $info);
        if (time() - $time > 1800) {
            throw RuntimeException::instance(Constant::ACTIVE_CODE_EXPIRE);
        }
        list($salt, $password) = PasswordHelper::encrypt($password);
        $info = array(
            'id' => $id,
            'password' => $password,
            'salt' => $salt,
        );
        $sql = 'UPDATE ' . $this->userTable . ' SET password=:password,salt=:salt WHERE id=:id';
        $ret = \App\Libs\Db\HeraPdo::write($sql, $info);
        // for log
        return $ret;
    }

    public function byEmail($info, $url) {
        $engine = new \App\Libs\Views\Smarty();
        $content = $engine->fetch(array('params' => array(
            'username' => $info['nickname'],
            'email' => $info['email'],
            'company' => COMPANY,
            'url' => $url,
        ), 'tpl' => 'mail/forgot_pwd.tpl.html'));
        \App\Libs\Helper\MailHelper::send($info['email'], COMPANY . '忘记密码重置邮件', $content);
    }

    public function byMobile($mobile) {
        \App\Libs\Captcha\SmsCaptcha::generate($mobile, 'forgot_pwd');
    }
}
